import * as THREE from 'three';

export class WaterSpray {
    constructor(options) {
        this.particleCount = options.particleCount || 20;
        this.startRandomSize = options.startRandomSize || new THREE.Vector3(8, 8, 8);
        this.targetPosition = options.targetPosition || new THREE.Vector3(40, 40, 40);
        this.endRandomSize = options.endRandomSize || new THREE.Vector3(25, 25, 25);
        this.particleMaterial = new THREE.PointsMaterial({
            color: options.color || 0xffffff,
            size: options.size || 8,
            transparent: true,
            map: options.map || new THREE.TextureLoader().load('./wu1.png'),
            depthWrite: false,    // 防止透明材质的深度写入
            // blending: THREE.AdditiveBlending, // 使用加法混合
            opacity: options.opacity || 1.0
        });
        this.particleSystem = null;
        // 创建粒子系统数组
        this.particleSystems = new THREE.Group();

        this.onComplete = options.onComplete;
        this.scene = options.scene;
        this.Timer = null;
        this.Timing = options.Timing || 4000;
        this.TWEEN = options.TWEEN;
    }
    // 创建和移动新粒子的函数
    createAndMoveParticles() {
        const particles = new THREE.BufferGeometry();
        const positions = new Float32Array(this.particleCount * 3); // 每个粒子3个坐标
        for (let i = 0; i < this.particleCount; i++) {
            positions[i * 3] = Math.random() * this.startRandomSize.x; // x 坐标
            positions[i * 3 + 1] = Math.random() * this.startRandomSize.y; // y 坐标
            positions[i * 3 + 2] = Math.random() * this.startRandomSize.z; // z 坐标
        }

        particles.setAttribute('position', new THREE.BufferAttribute(positions, 3));

        let particleSystem = new THREE.Points(particles, this.particleMaterial);
        this.particleSystems.add(particleSystem);
        return particleSystem;
    }
    // Function to create a random point within a circle
    randomCirclePoint(radius) {
        const angle = Math.random() * 2 * Math.PI;
        const r = radius * Math.sqrt(Math.random());
        return {
            x: r * Math.cos(angle),
            y: r * Math.sin(angle)
        };
    }

    // 移动粒子到指定位置
    moveParticles(particleSystem, targetPosition) {
        const particles = particleSystem.geometry;
        const startPositions = particles.attributes.position.array.slice();
        const endPositions = startPositions.slice();

        for (let i = 0; i < particles.attributes.position.count; i++) {
            endPositions[i * 3] = targetPosition.x + (Math.random()) * this.endRandomSize.x;
            endPositions[i * 3 + 1] = targetPosition.y + (Math.random()) * this.endRandomSize.y;
            endPositions[i * 3 + 2] = targetPosition.z + Math.random() * this.endRandomSize.z;
        }
        this.update({
            startPositions,
            particles,
            particleSystem,
            endPositions
        });
    }
    update({
        startPositions,
        particles,
        particleSystem,
        endPositions
    }) {
        let options = { startPositions, timing: 1 }
        new this.TWEEN.Tween(options)
            .to({
                startPositions: endPositions,
                timing: Math.PI  // sin的一个轮回
            }, this.Timing)
            .easing(this.TWEEN.Easing.Quadratic.Out)
            .onUpdate(() => {
                for (let i = 0; i < particles.attributes.position.count; i++) {
                    let sinY = Math.abs((Math.sin(options.timing) * options.startPositions[i * 3 + 1]) * 1);
                    particles.attributes.position.setXYZ(i, options.startPositions[i * 3], sinY, options.startPositions[i * 3 + 2]);
                }
                particles.attributes.position.needsUpdate = true;
            })
            .onComplete(() => {
                this.isAdd(this.onComplete, particleSystem, 'remove');
            })
            .start();
    }
    isAdd(callBack, particleSystem, type = 'add') {
        if (callBack) {
            callBack?.(particleSystem);
        } else {
            this.scene[type](particleSystem);
        }
    }
    create(callBackCreate) {
        let particleSystem = this.createAndMoveParticles();
        this.isAdd(callBackCreate, particleSystem);
        this.moveParticles(particleSystem, this.targetPosition);
    }
    createInterval(callBackCreate, Timing = 100) {
        // 定期创建和移动新粒子
        this.Timer = setInterval(() => {
            this.create(callBackCreate);
        }, Timing);
    }
    outInterval() {
        clearInterval(this.Timer);
    }
}